
function createMap(elId, centerLon, centerLat, zoom, options)
{
	var map = new YMaps.Map(YMaps.jQuery("#" + elId)[0]);	
	var geoResultMarker = null;
	map.setCenter( new YMaps.GeoPoint(centerLon, centerLat), zoom);
	map.addControl(new YMaps.TypeControl());			
	map.addControl(new YMaps.Zoom());			
	map.addControl(new YMaps.ScaleLine());
	map.addControl(new YMaps.ToolBar());
	
	if (options != null && options.showTraffic)
	{
		var traffic = new YMaps.Traffic.Control();
		map.addControl(traffic);
		traffic.show();
	}
	
	function setCenter(lat, lon, zoom)
	{
		map.setCenter( new YMaps.GeoPoint(lon, lat), zoom);
	}
	
	function showGeoResult(lat, lon)
	{
		map.removeOverlay(geoResultMarker);
		geoResultMarker = new YMaps.Placemark(new YMaps.GeoPoint(lon, lat),  
			{style: "default#houseIcon", draggable : true, hideIcon : false});					
		geoResultMarker.name = "Местоположение";
		geoResultMarker.description = "Меня можно перетаскивать<br>мышкой для задания более<br>точного положения!";						
		map.addOverlay(geoResultMarker);
	}
	
	function find(value, onFound, latlng)
	{
		map.removeOverlay(geoResultMarker);
		var geocoder = new YMaps.Geocoder(value, {results: 1, boundedBy: map.getBounds()});
		YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
			if (this.length()) 
			{
				var geoResult = this.get(0);
				map.setBounds(geoResult.getBounds());
				if (onFound)
				{				
					onFound(geoResult._point.__lat, geoResult._point.__lng, geoResult.precision == "exact");
				}
			}
			else 
			{
				if (onFound)
				{				
					onFound(0, 0, false);
				}
			}
		});

		YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (geocoder, error) {
			alert("Произошла ошибка: " + error);
		});
	}

	YMaps.Events.observe(map, map.Events.Click, function (map, mEvent) 
	{		
		if (returnObject.onClick)
		{
			returnObject.onClick(mEvent.getGeoPoint().__lat, mEvent.getGeoPoint().__lng);
		}
	});
	
	function addMarker(lat, lon, type, isDraggable, title, description)
	{
		var marker = new YMaps.Placemark(new YMaps.GeoPoint(lon, lat),  
			{style: "default#" + type, draggable : isDraggable, hideIcon : false});					
		marker.name = title;
		marker.description = description;
				
		var returnMarker = {marker: marker, 
			onDragEnd : null, 
			lat: function(){return marker._point.__lat;}, 
			lon: function(){return marker._point.__lng;}, 
			showInfo : function(){return marker.openBalloon();}
		};
		
		YMaps.Events.observe(marker, marker.Events.DragEnd, function (obj) 
			{ 				
				if (returnMarker.onDragEnd) 
				{					
					returnMarker.onDragEnd(); 
				}
			});
		
		map.addOverlay(marker);		
		return returnMarker;
	}
	
	function addPolyLine(arrayOfLatLonObjects, lineOptions)
	{
		var s = new YMaps.Style();
		s.lineStyle = new YMaps.LineStyle();
		s.lineStyle.strokeColor = lineOptions.color;
		s.lineStyle.strokeWidth = lineOptions.width;
		YMaps.Styles.add("default#CustomLine", s);
		
		var geoPoints = new Array();
		
		for (var i = 0; i < arrayOfLatLonObjects.length; i++)
		{
			geoPoints.push(new YMaps.GeoPoint(arrayOfLatLonObjects[i].longitude , arrayOfLatLonObjects[i].latitude));
		}
		 
		var pl = new YMaps.Polyline(geoPoints);

		pl.setStyle("default#CustomLine");
		map.addOverlay(pl);
	}
	
	function removeMarker(marker)
	{
		if (marker)
			map.removeOverlay(marker.marker);
	}
	
	function openBaloon(lat, lon, text)
	{
		map.openBalloon(new YMaps.GeoPoint(lon, lat), text);		
	}
	
	function setBounds(markers)	
	{
		var points = [];
		var forseSetBounds = false;
		for (var i = 0; i < markers.length; i++)
		{		
			points.push(markers[i].marker._point);
			if (!forseSetBounds && !map.getBounds().contains(markers[i].marker._point))
				forseSetBounds = true;
		}
		
		var bounds = new YMaps.GeoCollectionBounds(points)
		if (forseSetBounds)
			map.setBounds(bounds);
	}
	
	var returnObject = {map : map, find : find, addMarker: addMarker, removeMarker: removeMarker, setCenter: setCenter, onClick : null, openBaloon : openBaloon, setBounds: setBounds, addPolyLine: addPolyLine};
	return returnObject;
}